package samsung.sds.systemMonitor.SQLMonitor.intercept;

import java.util.HashMap;
import java.util.Properties;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; 

import samsung.sds.systemParamManagement.service.SystemParamManagementService;

/**
 * @author wei5.gao
 * @createDate 2016-02-22
 * 
 * SQL日志拦截器
 */
@Intercepts({
    @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }),
    @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
            RowBounds.class, ResultHandler.class }) })
@Component
public class SQLMonitorInterceptor implements  Interceptor , ApplicationContextAware {
	
	private static ApplicationContext applicationContext;
	private SystemParamManagementService systemParamManagementServiceImpl;
	
	/**
	 * 根据不同的interceptorType参数进行不同的拦截模式
	 */
	public Object intercept(Invocation invocation) throws Throwable {
	    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
	    String url = getUrl(attributes);
		String interceptorType = "";

	    if(url.endsWith(".do")){
	    	if(this.getsystemParamManagementServiceImpl().getSystemParamEntityFromCache("interceptorType") == null){
	    		interceptorType = "debug";
	    	}else{
	    		interceptorType = this.getsystemParamManagementServiceImpl().getSystemParamEntityFromCache("interceptorType").getParamVal();
	    	}
	    	
			HashMap<String ,Object> map=new HashMap<String ,Object>();
	    	map.put("interceptorType", interceptorType);
	    	map.put("invocation", invocation);
	    	return  SQLMoniterHandlerFactory.getInstance(interceptorType).saveSQLMonitorEntity(map);
	    }else{
	    	return invocation.proceed();
	    }
}
	/**
	 * mybaties拦截器固定的注入方法
	 */
	public Object plugin(Object target) {
	    return Plugin.wrap(target, this);
	}
	/**
	 * filter和intecepter中不能直接注入service，因此采用实现接口ApplicationContexAware，
	 * 使用set方法注入applicationCountext方式得到applicationContext对象
	 * ，根据显式的定义实例名拿到service
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		SQLMonitorInterceptor.applicationContext = applicationContext;
	}
	/**
	 * 获取xml中拦截器内的参数
	 */
	@Override
	public void setProperties(Properties properties) {
	}
	/**
	 * 获取url地址
	 * @param attributes
	 * @return
	 */
	private static String getUrl(ServletRequestAttributes attributes){
		String url = "";
    	if(attributes != null){
    		url = attributes.getRequest().getContextPath().toString()+attributes.getRequest().getServletPath().toString();
    	}
    	return url;
	}
	/**
	 * 获得系统参数的Service
	 * @param 
	 * @return
	 */	
	private SystemParamManagementService getsystemParamManagementServiceImpl() {
		if(this.systemParamManagementServiceImpl == null){
			systemParamManagementServiceImpl = (SystemParamManagementService) applicationContext.getBean("systemParamManagementServiceImpl");
		}
		return systemParamManagementServiceImpl;
	}
	

}
